package org.example.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.swagger.v3.oas.models.security.SecurityScheme;
import org.example.mapper.DApartmentMapper;
import org.example.mapper.DStaffRecordMapper;
import org.example.pojo.*;
import org.example.pojo.select.DStaffSelect;
import org.example.pojo.select.ExceptionStaffSelect;
import org.example.pojo.select.PendingStaffSelect;
import org.example.pojo.select.ResignStaffSelect;
import org.example.service.DStaffService;
import org.example.mapper.DStaffMapper;
import org.example.utils.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
* @author chenhongkai
* @description 针对表【d_staff】的数据库操作Service实现
* @createDate 2024-03-11 10:20:48
*/
@Service
public class DStaffServiceImpl extends ServiceImpl<DStaffMapper, DStaff>
    implements DStaffService{

    @Autowired
    private DStaffMapper dStaffMapper;

    @Autowired
    private DApartmentMapper dApartmentMapper;

    @Autowired
    private DStaffRecordMapper dStaffRecordMapper;

    @Override
    public Result<Map> SelectPendingStaff(PendingStaffSelect pendingStaffSelect) {
        Integer pendingStaffsTotal = dStaffMapper.SelectPendingStaffsTotal(pendingStaffSelect);
        List<DStaff> staffList = dStaffMapper.SelectPendingStaff(pendingStaffSelect);

        Map pendingStaffMap = new HashMap<>();

        pendingStaffMap.put("pageTotal",pendingStaffsTotal);
        pendingStaffMap.put("pendingStaffData",staffList);

        return Result.ok(pendingStaffMap);
    }

    @Override
    public Result<Map> SelectAllStaffs(DStaffSelect dStaffSelect){
//        long startTime=System.currentTimeMillis();
//        long endTime1=System.currentTimeMillis();
//        System.out.println("程序运行时间1： "+(endTime1-startTime)+"ms");

        //分页查询员工
        Page<DStaff> page = new Page<>(dStaffSelect.getCurrentPage(),dStaffSelect.getPageSize());

        //关闭插件的count查询
        page.setSearchCount(false);
        Long staffsTotal = dStaffMapper.SelectAllStaffs_total(dStaffSelect);

        //自定义设置分页总数
        page.setTotal(staffsTotal);
        IPage<DStaff> mapIPage = dStaffMapper.SelectAllStaffs(page,dStaffSelect);


        Map staffMap = new HashMap<>();
        staffMap.put("pageSize",mapIPage.getSize());
        staffMap.put("pageTotal",mapIPage.getTotal());
        staffMap.put("staffData",mapIPage.getRecords());


        return Result.ok(staffMap);
    }

    @Override
    public Result<DStaff> DeleteApartmentStaffs(List<DStaff> dStaffList) {
        //批量删除员工
        for(DStaff staff : dStaffList){
            //更新时间
            staff.setUpdateDate(new Date());
            staff.setCheckInDate(new Date());
//            dApartmentMapper.AddApartmentVacancy(staff.getApartmentId());

            //记录员工宿舍变化
            DStaffRecord dStaffRecord = new DStaffRecord();
            dStaffRecord.setSid(staff.getSid());
            dStaffRecord.setOldApartmentId(staff.getApartmentId());
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            dStaffRecord.setNewApartmentId("离宿："+sdf.format(new Date()));
            dStaffRecordMapper.insert(dStaffRecord);

            //移除在住员工
            dStaffMapper.DeleteStaff(staff.getSid());

        }
        return Result.ok(null);
    }

    @Override
    public Result<DStaff> AddApartmentStaffs(DStaffSelect dStaffSelect) {
        //批量增加员工
        for(DStaff staff : dStaffSelect.getStaffs()){
            //更新时间
            staff.setUpdateDate(new Date());
            staff.setCheckInDate(new Date());

            //筛选宿舍中改变的人员信息
            if(!Objects.equals(dStaffSelect.getApartmentId(), staff.getApartmentId())){
                //记录员工宿舍变化
                DStaffRecord dStaffRecord = new DStaffRecord();
                dStaffRecord.setSid(staff.getSid());
                dStaffRecord.setOldApartmentId(staff.getApartmentId());
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                dStaffRecord.setNewApartmentId(dStaffSelect.getApartmentId()+"(换宿时间"+sdf.format(new Date())+")");
                dStaffRecordMapper.insert(dStaffRecord);

                //旧宿舍增加空位数量
                dApartmentMapper.AddApartmentVacancy(staff.getApartmentId());

                //逻辑删除，离宿处理
                staff.setCheckOutDate(new Date());
                dStaffMapper.DeleteStaffBySid(staff);

                //换宿舍，重新加入
                staff.setSid(null);
                staff.setCheckOutDate(null);
                dStaffMapper.insertStaffB(staff);
                staff.setApartmentId(dStaffSelect.getApartmentId());
                dStaffMapper.updateById(staff);
            }
        }
        return Result.ok(null);
    }

    @Override
    public Result<Integer> UpdateStaffApartment(DStaffSelect dStaff) {
//        System.out.println("dStaff = " + dStaff);
        //格式化时间
        SimpleDateFormat formatter  = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = formatter.parse(dStaff.getCheckInDate());
        } catch (ParseException e) {
            e.printStackTrace();
        }

        //检查床位是否充足
        LambdaQueryWrapper<DApartment> apartmentLambdaQueryWrapper = new LambdaQueryWrapper<>();
        apartmentLambdaQueryWrapper.eq(DApartment::getApartmentId,dStaff.getApartmentId());
        DApartment dApartment = dApartmentMapper.selectOne(apartmentLambdaQueryWrapper);
        if(dStaff.getStaffs().length > dApartment.getVacancy())
            return Result.warning(501,"宿舍床位不足");

        for(DStaff dStaffA : dStaff.getStaffs()){

            LambdaQueryWrapper<DStaff> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(DStaff::getSid,dStaffA.getSid());
            DStaff dStaffSelect = dStaffMapper.selectOne(lambdaQueryWrapper);

            //判断更新是否更新宿舍
            int updateType = 0;

            //判断是否换宿舍
            if(!Objects.equals(dStaffSelect.getApartmentId(), dStaff.getApartmentId())){
                //人员的宿舍被更新
                updateType = 1;
                //原宿舍增加床位
                dApartmentMapper.AddApartmentVacancy(dStaffSelect.getApartmentId());
                //现宿舍减少床位
                dApartmentMapper.DeleteApartmentVacancy(dStaff.getApartmentId());
            }

            //宿舍若更新则操作换宿
            if(updateType == 1) {
                //记录员工宿舍变化
                DStaffRecord dStaffRecord = new DStaffRecord();
                dStaffRecord.setSid(dStaffSelect.getSid());
                dStaffRecord.setOldApartmentId(dStaffSelect.getApartmentId());
                dStaffRecord.setNewApartmentId(dStaff.getApartmentId()+"(换宿时间"+dStaff.getCheckInDate()+")");
                dStaffRecordMapper.insert(dStaffRecord);

                //逻辑删除
                dStaffA.setCheckOutDate(date);//加入退宿时间
                dStaffMapper.DeleteStaffBySid(dStaffA);

                //重新初始化数据后,新增新的记录
                DStaff dStaffB = new DStaff();
                dStaffB.setApartmentId(dStaff.getApartmentId());
                dStaffB.setCheckInDate(date);
                dStaffB.setStaffTepId(dStaffA.getStaffTepId());

                int row = dStaffMapper.insertStaffB(dStaffB);

                if(row == 0) return Result.error("重新插入人员信息失败");
            }
        }

        return Result.ok(null);
    }

    @Override
    public Result<DStaff> SelectOneByName(DStaff dStaff) {
        DStaff selectStaff = dStaffMapper.selectByName(dStaff);
        return Result.ok(selectStaff);
    }

    @Override
    public Result<DStaff> SelectOneById(DStaff dStaff) {
        DStaff selectStaff = dStaffMapper.selectByStaffId(dStaff.getStaffId());
        return Result.ok(selectStaff);
    }

    @Override
    public Result<DStaff> AddStaffs(DStaffSelect dStaffSelect) {
        //由宿舍号和宿舍剩余床位组成的map变量
        Map<String, Integer> apartmentVacancyMap = new HashMap<>();
        for (DStaff staff : dStaffSelect.getStaffs()) {
            if(staff.getApartmentId() != null){
                apartmentVacancyMap.put(staff.getApartmentId(), apartmentVacancyMap.getOrDefault(staff.getApartmentId(), 0) + 1);
            }
        }

        //验证添加员工的,各个宿舍床位剩余床位是否充足
        for (Map.Entry<String, Integer> entry : apartmentVacancyMap.entrySet()) {
            LambdaQueryWrapper<DApartment> dApartmentLambdaQueryWrapper = new LambdaQueryWrapper<>();
            dApartmentLambdaQueryWrapper.eq(DApartment::getApartmentId,entry.getKey());
            DApartment selectApartment = dApartmentMapper.selectOne(dApartmentLambdaQueryWrapper);
            if(selectApartment != null && selectApartment.getVacancy() < entry.getValue())
                return Result.warning(503,selectApartment.getApartmentId()+"宿舍房间剩余床位不足");
        }


        for(DStaff dStaff : dStaffSelect.getStaffs()){
            //验证房间是否已满
            LambdaQueryWrapper<DApartment> lambdaQueryWrapperApartment = new LambdaQueryWrapper<>();
            lambdaQueryWrapperApartment.eq(DApartment::getApartmentId,dStaff.getApartmentId());
            DApartment selectApartment = dApartmentMapper.selectOne(lambdaQueryWrapperApartment);
            if(selectApartment != null && selectApartment.getVacancy() <= 0)
                return Result.warning(502,selectApartment.getApartmentId()+"房间已满");

            //是否有同步ID
            DStaff selectStaff = dStaffMapper.selectEmpByStaffId(dStaff.getStaffId());
            //是否存在相同工号
            if(selectStaff != null){
                DStaff selectOne = dStaffMapper.selectByStaffId(selectStaff.getStaffId());
                if(selectOne != null) return Result.warning(501,"已存在相同工号员工");
                dStaff.setStaffTepId(selectStaff.getStaffTepId());
            }

            //减少所换宿舍的空余床位
            if(selectApartment != null)
                dApartmentMapper.DeleteApartmentVacancy(selectApartment.getApartmentId());

            //把信息添加到临时为临时数(如果在人事系统未找到)
            if(selectStaff == null){
                DStaff dStaff_temporary = new DStaff();
                dStaff_temporary.setApartmentId(dStaff.getApartmentId());
                dStaff_temporary.setTemEmpNo(dStaff.getStaffId());
                dStaff_temporary.setTemEmpName(dStaff.getStaffName());
                dStaff_temporary.setTemIdCard(dStaff.getStaffIdCard());
                dStaff_temporary.setTemPhoneNumber(dStaff.getStaffPhoneNumber());
                try{
                    dStaffMapper.insert(dStaff_temporary);
                }catch (Exception e){
//                    e.printStackTrace();
                }
            }else{
                try{
                    //添加人员带宿舍(返回sid,在dStaff对象中获取)
                    dStaffMapper.insertStaff(dStaff);
                }catch (Exception e){
//                    e.printStackTrace();
                }
            }
        }

        return Result.ok(null);
    }

    @Override
    public Result<DStaff> UpdateStaffStatus(DStaff dStaff) {
//        System.out.println("dStaff = " + dStaff);
        int row = dStaffMapper.UpdateStaffStatus(dStaff);
        if(row == 0) return Result.error("删除入住人员失败");
        return Result.ok(null);
    }

    @Override
    public Result<Map> selectStaffPhoneNumber(DStaff dStaff) {
        DStaff selectDStaff = dStaffMapper.selectStaffPhoneNumber(dStaff.getSid());
        Map dstaffMap = new HashMap();
        dstaffMap.put("staffPhoneNumber",selectDStaff.getStaffPhoneNumber());
        return Result.ok(dstaffMap);
    }

    @Override
    public Result<Map> AddPendingStaff(DStaffSelect dStaffSelect) {
        for(DStaff dStaff : dStaffSelect.getStaffs() ){
            //是否存在相同的同步id
            LambdaQueryWrapper<DStaff> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(DStaff::getStaffTepId,dStaff.getStaffTepId());
            DStaff selectStaff = dStaffMapper.selectOne(lambdaQueryWrapper);
            if(selectStaff != null) return Result.warning(501,"已存在相同的TEPId");
            try{
                //添加人员带宿舍(返回sid,在dStaff对象中获取)
                dStaffMapper.insert(dStaff);
            }catch (Exception e){
//                    e.printStackTrace();
            }

            //减少宿舍床位
            dApartmentMapper.DeleteApartmentVacancy(dStaff.getApartmentId());
        }
        return Result.ok(null);
    }

    @Override
    public Result<Map> SelectResignStaff(ResignStaffSelect resignStaffSelect) {

        Page<DStaff> page = new Page<>(resignStaffSelect.getCurrentPage(),resignStaffSelect.getPageSize());
        page.setSearchCount(false);

        Integer resignStaffsTotal = dStaffMapper.SelectResignStaffTotal(resignStaffSelect);
        page.setTotal(resignStaffsTotal);

        IPage<Map> mapIPage = dStaffMapper.SelectResignStaff(page,resignStaffSelect);

        Map recordMap = new HashMap<>();
        recordMap.put("pageSize",mapIPage.getSize());
        recordMap.put("pageTotal",mapIPage.getTotal());
        recordMap.put("ResignStaffData",mapIPage.getRecords());

        return Result.ok(recordMap);
    }

    @Override
    public Result<Map> DeleteResignStaff(ResignStaffSelect resignStaffSelect) {
        for(DStaff dStaff : resignStaffSelect.getStaffs()){

            //减少宿舍空位
            dApartmentMapper.AddApartmentVacancy(dStaff.getApartmentId());


//            //判断是离职还是外宿
//            if(Objects.equals(dStaff.getEmpStatus(), "离职")){
//                int row = dStaffMapper.DeleteResignStaff(dStaff.getStaffTepId());
                int row = dStaffMapper.DeleteResignStaff(dStaff);
                if(row == 0) return Result.error("退宿失败");
//            }else{
//                dStaff.setApartmentId("W外宿");
//                dStaff.setCheckInDate(new Date());
//                dStaffMapper.updateApartment(dStaff);
//            }

            //记录员工宿舍变化
            DStaffRecord dStaffRecord = new DStaffRecord();
            dStaffRecord.setSid(dStaff.getSid());
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            dStaffRecord.setOldApartmentId(dStaff.getApartmentId());
            dStaffRecord.setNewApartmentId("离宿："+sdf.format(dStaff.getCheckOutDate()));
//            dStaffRecord.setUpdateDate(dStaff.getCheckOutDate());//调动时间为离开宿舍时间
            dStaffRecordMapper.insert(dStaffRecord);
        }
        return Result.ok(null);
    }

    @Override
    public Result<Map> SelectExceptionStaff(ExceptionStaffSelect exceptionStaffSelect) {
        Page<DStaff> page = new Page<>(exceptionStaffSelect.getCurrentPage(),exceptionStaffSelect.getPageSize());
        page.setSearchCount(false);

        Integer exceptionStaffsTotal = dStaffMapper.SelectExceptionStaffTotal(exceptionStaffSelect);
        page.setTotal(exceptionStaffsTotal);

        IPage<Map> mapIPage = dStaffMapper.SelectExceptionStaff(page,exceptionStaffSelect);

        Map recordMap = new HashMap<>();
        recordMap.put("pageSize",mapIPage.getSize());
        recordMap.put("pageTotal",mapIPage.getTotal());
        recordMap.put("exceptionStaffData",mapIPage.getRecords());

        return Result.ok(recordMap);
    }

    @Override
    public Result<Map> SelectAllDownStaffs() {

        List<DStaff> dStaffList = dStaffMapper.SelectAllDownStaffs();
        Map staffMap = new HashMap<>();
        staffMap.put("staffData",dStaffList);
        return Result.ok(staffMap);
    }

    @Override
    public Result<DStaff> DeleteStaff(DStaff dStaff) {
        //查出需要备份的数据
//        DStaff staffBak = dStaffMapper.selectById(dStaff);

        //增加房间空间
        if(dStaff.getIsDeleted() == 1){
            dApartmentMapper.AddApartmentVacancy(dStaff.getApartmentId());
        }
        int row = dStaffMapper.deleteById(dStaff);
        if(row == 0) return Result.error("人员实际删除失败");
        //备份
//        dStaffMapper.insertStaffBak(staffBak,"删除");
        return Result.ok(null);
    }

    @Override
    public Result<DStaff> UpdateStaff(DStaff dStaff) {
        int row = dStaffMapper.updateById(dStaff);
        if(row == 0) return Result.error("人员信息修改失败");
        return Result.ok(null);
    }

    @Override
    public Result<Map> SelectStaffInfo(DStaffSelect dStaffSelect) {
        List<DStaff> dStaffList = dStaffMapper.SelectStaffInfo(dStaffSelect);
        Map staffMap = new HashMap<>();
        staffMap.put("staffData",dStaffList);
        return Result.ok(staffMap);
    }

    @Override
    public Result<Integer> exception_resignStaffCount() {
        ResignStaffSelect resignStaffSelect = new ResignStaffSelect();
        Integer count1 = dStaffMapper.SelectResignStaffTotal(resignStaffSelect);

        ExceptionStaffSelect exceptionStaffSelect = new ExceptionStaffSelect();
        Integer count2 = dStaffMapper.SelectExceptionStaffTotal(exceptionStaffSelect);
        return Result.ok(count1+count2);
    }

    @Override
    public Result<Integer> pending_staffCount() {
        PendingStaffSelect pendingStaffSelect = new PendingStaffSelect();
        Integer count = dStaffMapper.SelectPendingStaffsTotal(pendingStaffSelect);
        return Result.ok(count);
    }


}




